package com.da.javatest.util;



import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoField;
import java.time.temporal.ChronoUnit;
import java.time.temporal.TemporalField;
import java.util.Arrays;
import java.util.Date;
import java.util.Set;
import java.util.TimeZone;
import java.util.stream.Collectors;

/**
 * @author 南谦
 * @date 2020-05-18
 */
public class ZonedTimeUtils {
    /**
     * UTC+8时区
     * @return
     */
     public static TimeZone utc8TimeZone(){
         return TimeZone.getTimeZone("Asia/Shanghai");
     }

    /**
     * UTC0时区
     * @return
     */
    public static TimeZone utc0TimeZone(){
        return TimeZone.getTimeZone("UTC");
    }

    /**
     * 当前UTC+8的时间
     * @return
     */
    public static ZonedDateTime nowUTC8Time(){
        return ZonedDateTime.now(utc8TimeZone().toZoneId());
    }


    /**
     * 转化成UTC+8时间
     * @param date
     * @return
     */
    public static ZonedDateTime toUTC8(Date date){
        return toZonedTime(date,utc8TimeZone());
    }


    /**
     * 转换成date
     * @param dateStr
     * @param pattern
     * @param sourceTimeZone 日期字符串来源时区
     * @return
     */
    public static Date toDate(String dateStr, String pattern, TimeZone sourceTimeZone){
        DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern(pattern).withZone(sourceTimeZone.toZoneId());
        ZonedDateTime zonedDateTime = ZonedDateTime.parse(dateStr, dateTimeFormatter);
        return toDate(zonedDateTime);
    }


    /**
     * 转换成date
     * @param zonedDateTime
     * @return
     */
    public static Date toDate(ZonedDateTime zonedDateTime){
        return Date.from(zonedDateTime.toInstant());
    }


    /**
     * 讲date转化成目标时区时间
     * @param date
     * @param targetTimeZone 目标时区
     * @return
     */
    public static ZonedDateTime toZonedTime(Date date, TimeZone targetTimeZone){
        return ZonedDateTime.ofInstant(date.toInstant(),targetTimeZone.toZoneId());
    }


    /**
     * 将dateStr字符串转化成目标时区时间
     * @param dateStr
     * @param pattern
     * @param sourceTimeZone dateStr的来源时区
     * @param targetTimeZone 目标时区
     * @return
     */
    public static ZonedDateTime toZonedTime(String dateStr, String pattern, TimeZone sourceTimeZone, TimeZone targetTimeZone){
        Date date = toDate(dateStr, pattern, sourceTimeZone);
        return toZonedTime(date,targetTimeZone);

    }


    /**
     * 将UTC+8的dateStr字符串转化成目标时区时间
     * @param dateStr
     * @param pattern
     * @param targetTimeZone
     * @return
     */
    public static ZonedDateTime utc8ToZonedTime(String dateStr, String pattern, TimeZone targetTimeZone){
        return toZonedTime(dateStr,pattern,utc8TimeZone(),targetTimeZone);
    }



    /**
     * 讲一个zonedDateTime转化成目标时区zonedDateTime
     * @param zonedDateTime
     * @param targetTimeZone
     * @return
     */
    public static ZonedDateTime toZonedTime(ZonedDateTime zonedDateTime, TimeZone targetTimeZone){
        return ZonedDateTime.ofInstant(zonedDateTime.toInstant(),targetTimeZone.toZoneId());
    }


    /**
     * 格式转化
     * @param zonedDateTime
     * @param pattern
     * @return
     */
    public static String format(ZonedDateTime zonedDateTime, String pattern){
        DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern(pattern);
        return dateTimeFormatter.format(zonedDateTime);
    }

    /**
     * 获取有效的时区id
     * eg. "Asia/Shanghai"
     *
     * @return
     */
    public static Set<String> getAvailableTimeZoneIDs() {
        return Arrays.stream(TimeZone.getAvailableIDs()).collect(Collectors.toSet());
    }


    public static void main(String[] args) {
        System.out.println(utc8TimeZone());
        System.out.println(utc0TimeZone());
        System.out.println(nowUTC8Time());
        System.out.println(ZonedTimeUtils.toUTC8(new Date()));
        System.out.println("---------------------------------------");
        System.out.println(ZonedTimeUtils.toDate("2020-01-01 12:12","yyyy-MM-dd HH:mm",TimeZone.getTimeZone("Europe/Moscow")));
        System.out.println(ZonedTimeUtils.toDate(ZonedDateTime.now()));
        System.out.println(ZonedTimeUtils.toDate(ZonedDateTime.now(ZoneId.of("Europe/Moscow"))));
        System.out.println(ZonedTimeUtils.toZonedTime(new Date(),TimeZone.getTimeZone("Europe/Moscow")));
        System.out.println(ZonedTimeUtils.toZonedTime(new Date(),TimeZone.getTimeZone("Asia/Shanghai")));
        System.out.println(ZonedTimeUtils.toZonedTime("2020-01-01 12:12","yyyy-MM-dd HH:mm",TimeZone.getTimeZone("Europe/Moscow"),TimeZone.getTimeZone("Asia/Shanghai")));
        System.out.println(ZonedTimeUtils.toZonedTime("2020-01-01 12:12","yyyy-MM-dd HH:mm",TimeZone.getTimeZone("Asia/Shanghai"),TimeZone.getTimeZone("Europe/Moscow")));
        System.out.println(ZonedTimeUtils.utc8ToZonedTime("2020-01-01 12:12","yyyy-MM-dd HH:mm",TimeZone.getTimeZone("Europe/Moscow")));
        System.out.println(ZonedTimeUtils.toZonedTime(ZonedDateTime.now(),TimeZone.getTimeZone("Europe/Moscow")));
        System.out.println(ZonedTimeUtils.format( ZonedDateTime.now(TimeZone.getTimeZone("Europe/Moscow").toZoneId()),"yyyy-MM-dd HH-mm"));
        //for (String availableTimeZoneID : ZonedTimeUtils.getAvailableTimeZoneIDs()) {
        //    System.out.println(availableTimeZoneID);
        //}

        System.out.println("---------------------------------------");
        String temp = "yyyy-MM-dd HH:mm:ss";
        ZonedDateTime zonedDateTime = ZonedTimeUtils.toZonedTime(new Date(), TimeZone.getTimeZone("Europe/Moscow"));
        //转化成字符串
        String str = ZonedTimeUtils.format(zonedDateTime, temp);
        System.out.println(str);
        Date toDate = ZonedTimeUtils.toDate(str, temp, TimeZone.getTimeZone("Asia/Shanghai"));
        System.out.println(toDate);
    }

}
